package site.isscloud.quartz.task;

import com.alibaba.fastjson2.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import site.isscloud.common.utils.StringUtils;
import site.isscloud.project.mqtt.ProjectMqttService;
import site.isscloud.project.mqtt.dto.TemperatureMqttDto;
import site.isscloud.project.constants.BusinessConstants;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 改进版温度数据模拟任务 - 支持时间维度和升温过程
 */
@Component("temperatureTask")
public class TemperatureTask
{
    private static final Logger log = LoggerFactory.getLogger(TemperatureTask.class);

    @Autowired(required = false)
    private ProjectMqttService mqttService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    // 温度变化参数配置（改为秒为单位，因为任务每5秒执行一次）
    private static final int HIGH_TEMP_METER_COUNT = BusinessConstants.HIGH_TEMP_METER_COUNT; // 每个设备+通道的高温米标数量
    private static final int WARM_UP_DURATION_SECONDS = BusinessConstants.WARM_UP_DURATION_SECONDS;    // 升温持续120秒（2分钟）
    private static final int HIGH_TEMP_DURATION_SECONDS = BusinessConstants.HIGH_TEMP_DURATION_SECONDS;  // 高温持续300秒（5分钟）
    private static final int COOL_DOWN_DURATION_SECONDS = BusinessConstants.COOL_DOWN_DURATION_SECONDS;  // 降温持续180秒（3分钟）
    private static final int COOL_DOWN_INTERVAL_SECONDS = BusinessConstants.COOL_DOWN_INTERVAL_SECONDS; // 降温后3600秒内不再升温（60分钟）
    private static final int WARM_UP_START_INTERVAL_SECONDS = BusinessConstants.WARM_UP_START_INTERVAL_SECONDS; // 米标开始升温的时间间隔60秒

    private static final double BASE_TEMP_MIN = BusinessConstants.BASE_TEMP_MIN;          // 基础温度下限
    private static final double BASE_TEMP_MAX = BusinessConstants.BASE_TEMP_MAX;          // 基础温度上限
    private static final double ABNORMAL_TEMP_BASE = BusinessConstants.ABNORMAL_TEMP_BASE;     // 异常温度基准
    private static final double ABNORMAL_TEMP_RANGE = BusinessConstants.ABNORMAL_TEMP_RANGE;    // 异常温度范围

    // 存储设备的高温米标映射（设备+通道 -> 高温米标列表）
    private static final Map<String, List<Integer>> deviceHighTempMeters = new ConcurrentHashMap<>();

    // 存储设备状态（设备+通道 -> 温度状态映射）
    private static final Map<String, DeviceTemperatureState> deviceStates = new ConcurrentHashMap<>();

    // 改为静态的 Random 实例
    private static final Random random = new Random();

    /**
     * 设备温度状态类
     */
    private static class DeviceTemperatureState {
        LocalDateTime lastCoolDownTime;  // 上次降温完成时间
        Map<Integer, MeterTemperatureState> meterStates = new ConcurrentHashMap<>(); // 米标状态
        LocalDateTime firstWarmUpStartTime; // 第一个米标开始升温的时间
        int warmUpSequence = 0; // 升温序列计数器

        // 检查是否在冷却期内
        boolean isInCoolDownPeriod() {
            if (lastCoolDownTime == null) return false;
            return LocalDateTime.now().isBefore(lastCoolDownTime.plusSeconds(COOL_DOWN_INTERVAL_SECONDS));
        }

        // 获取下一个米标的升温开始时间
        LocalDateTime getNextWarmUpStartTime() {
            if (firstWarmUpStartTime == null) {
                firstWarmUpStartTime = LocalDateTime.now();
                warmUpSequence = 0;
                return firstWarmUpStartTime;
            }

            warmUpSequence++;
            return firstWarmUpStartTime.plusSeconds(warmUpSequence * WARM_UP_START_INTERVAL_SECONDS);
        }

        // 重置升温序列（当所有米标都完成降温后）
        void resetWarmUpSequence() {
            firstWarmUpStartTime = null;
            warmUpSequence = 0;
        }

        // 检查是否所有米标都处于正常状态
        boolean allMetersNormal() {
            for (MeterTemperatureState meterState : meterStates.values()) {
                if (meterState.phase != TemperaturePhase.NORMAL) {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * 米标温度状态类
     */
    private static class MeterTemperatureState {
        int meter;                      // 米标位置
        TemperaturePhase phase;         // 当前阶段
        LocalDateTime phaseStartTime;   // 阶段开始时间
        LocalDateTime scheduledWarmUpTime; // 计划开始升温的时间
        double startTemperature;        // 阶段开始时的温度
        double targetTemperature;       // 目标温度
        double currentTemperature;      // 当前温度
        double baseHighTemperature;     // 高温阶段的基础温度（用于波动计算）

        // 在静态内部类中创建自己的 Random 实例
        private final Random meterRandom = new Random();

        // 检查是否到达计划升温时间
        boolean isWarmUpTimeReached() {
            if (scheduledWarmUpTime == null) return false;
            return LocalDateTime.now().isAfter(scheduledWarmUpTime) ||
                    LocalDateTime.now().equals(scheduledWarmUpTime);
        }

        // 计算当前阶段的进度（0-1）
        double getPhaseProgress() {
            if (phaseStartTime == null) return 0.0;
            long elapsed = java.time.Duration.between(phaseStartTime, LocalDateTime.now()).getSeconds();
            long totalDuration = getPhaseDurationSeconds();
            return Math.min(1.0, (double) elapsed / totalDuration);
        }

        // 获取阶段持续时间（秒）
        private long getPhaseDurationSeconds() {
            switch (phase) {
                case WARMING_UP: return WARM_UP_DURATION_SECONDS;
                case HIGH_TEMP: return HIGH_TEMP_DURATION_SECONDS;
                case COOLING_DOWN: return COOL_DOWN_DURATION_SECONDS;
                default: return 0;
            }
        }

        // 生成高温阶段的微小波动（±1.5°C）
        private double generateHighTempFluctuation() {
            return (meterRandom.nextDouble() - 0.5) * 3.0; // -1.5°C 到 +1.5°C 的波动
        }

        // 更新当前温度（基于阶段进度）
        void updateCurrentTemperature() {
            double progress = getPhaseProgress();
            switch (phase) {
                case WARMING_UP:
                    currentTemperature = startTemperature + (targetTemperature - startTemperature) * progress;
                    // 修正日志格式
                    log.debug("升温中 - 米标: {}, 进度: {:.2f}%, 当前温度: {:.1f}, 目标温度: {:.1f}",
                            meter, progress * 100, currentTemperature, targetTemperature);
                    break;
                case COOLING_DOWN:
                    currentTemperature = startTemperature - (startTemperature - targetTemperature) * progress;
                    // 修正日志格式
                    log.debug("降温中 - 米标: {}, 进度: {:.2f}%, 当前温度: {:.1f}, 目标温度: {:.1f}",
                            meter, progress * 100, currentTemperature, targetTemperature);
                    break;
                case HIGH_TEMP:
                    double fluctuation = generateHighTempFluctuation();
                    currentTemperature = baseHighTemperature + fluctuation;
                    currentTemperature = Math.max(currentTemperature, baseHighTemperature - 2.0);
                    // 修正日志格式
                    log.debug("高温持续 - 米标: {}, 基础温度: {:.1f}, 波动: {:.1f}, 当前温度: {:.1f}",
                            meter, baseHighTemperature, fluctuation, currentTemperature);
                    break;
                default:
                    currentTemperature = targetTemperature;
            }
        }

        // 检查阶段是否完成
        boolean isPhaseCompleted() {
            return getPhaseProgress() >= 1.0;
        }

        // 计算每5秒的温度变化量（用于调试）
        double getTemperatureChangePer5Seconds() {
            if (phase == TemperaturePhase.WARMING_UP) {
                return (targetTemperature - startTemperature) * (5.0 / WARM_UP_DURATION_SECONDS);
            } else if (phase == TemperaturePhase.COOLING_DOWN) {
                return (startTemperature - targetTemperature) * (5.0 / COOL_DOWN_DURATION_SECONDS);
            }
            return 0.0;
        }
    }

    /**
     * 温度阶段枚举
     */
    private enum TemperaturePhase {
        NORMAL,         // 正常温度
        WAITING_WARM_UP, // 等待升温（已分配升温时间但未到时间）
        WARMING_UP,     // 升温中
        HIGH_TEMP,      // 高温持续
        COOLING_DOWN    // 降温中
    }

    // 在 TemperatureTask 中添加发送MQTT数据的方法
    /**
     * 改进版温度数据生成 - 通过MQTT发布数据
     */
    public void generateTemperatureMQTTDataAdv(String configs) {
        try {
            log.info("开始执行改进版温度数据模拟任务(MQTT) - {}", LocalDateTime.now());

            if (StringUtils.isEmpty(configs)) {
                log.warn("温度数据模拟任务参数为空，使用默认配置");
                return;
            }

            String[] configArray = configs.split(",");
            int totalRecords = 0;

            for (String config : configArray) {
                String trimmedConfig = config.trim();
                if (StringUtils.isEmpty(trimmedConfig)) {
                    continue;
                }

                String[] parts = trimmedConfig.split("-");
                if (parts.length != 4) {
                    log.error("配置格式错误，跳过: {}", trimmedConfig);
                    continue;
                }

                try {
                    String deviceNo = parts[0].trim();
                    int channelNo = Integer.parseInt(parts[1].trim());
                    int startMeter = Integer.parseInt(parts[2].trim());
                    int endMeter = Integer.parseInt(parts[3].trim());

                    if (startMeter < 1 || endMeter < startMeter) {
                        log.error("米标范围无效，跳过: {} ({} - {})", trimmedConfig, startMeter, endMeter);
                        continue;
                    }

                    // 获取或生成高温米标（保持一致性）
                    List<Integer> highTempMeters = getOrGenerateHighTempMeters(deviceNo, channelNo, startMeter, endMeter);

                    // 生成温度数据（只生成温度数组，不处理异常）
                    TemperatureMqttDto mqttData = generateTemperatureDataForMqtt(
                            deviceNo, channelNo, startMeter, endMeter, highTempMeters);

                    // 通过MQTT发送数据
                    boolean success = mqttService.publishRealtimeData(mqttData);

                    if (success) {
                        totalRecords++;
                        if (totalRecords % 12 == 0) {
                            log.info("MQTT发布温度数据成功 - 设备: {}, 通道: {}, 米标范围: {}-{}, 高温米标数: {}",
                                    deviceNo, channelNo, startMeter, endMeter, highTempMeters.size());
                        }
                    } else {
                        log.error("MQTT发布温度数据失败 - 设备: {}, 通道: {}", deviceNo, channelNo);
                    }

                } catch (NumberFormatException e) {
                    log.error("配置参数格式错误，跳过: {}", trimmedConfig, e);
                }
            }

            log.info("改进版温度数据模拟任务(MQTT)执行完成 - 成功发布了 {} 条记录 - {}", totalRecords, LocalDateTime.now());

        } catch (Exception e) {
            log.error("改进版温度数据模拟任务(MQTT)执行失败", e);
        }
    }

    /**
     * 生成用于MQTT传输的温度数据（不处理异常数据存储）
     */
    private TemperatureMqttDto generateTemperatureDataForMqtt(String deviceNo, int channelNo,
                                                              int startMeter, int endMeter,
                                                              List<Integer> highTempMeters) {
        String deviceKey = deviceNo + "-" + channelNo;
        DeviceTemperatureState deviceState = deviceStates.computeIfAbsent(deviceKey,
                k -> new DeviceTemperatureState());

        int markerCount = endMeter - startMeter + 1;
        List<BigDecimal> maxTemperatures = new ArrayList<>(markerCount);
        List<BigDecimal> minTemperatures = new ArrayList<>(markerCount);

        // 存储本批次需要发送告警的米标
        List<Map<String, Object>> alarmMeters = new ArrayList<>();

        // 基础温度
        double baseTemp = BASE_TEMP_MIN + random.nextDouble() * (BASE_TEMP_MAX - BASE_TEMP_MIN);

        for (int i = 0; i < markerCount; i++) {
            int currentMeter = startMeter + i;
            double maxTemp = baseTemp + random.nextDouble() * 3.0;
            double minTemp = baseTemp - random.nextDouble() * 2.0;

            // 检查是否是高温米标并处理温度状态
            if (highTempMeters.contains(currentMeter)) {
                MeterTemperatureState meterState = deviceState.meterStates.computeIfAbsent(
                        currentMeter, k -> createNewMeterState(currentMeter, baseTemp, deviceState));

                // 更新米标温度状态
                updateMeterTemperatureState(meterState, deviceState);

                // 使用当前计算出的温度
                maxTemp = meterState.currentTemperature;

                // 检查是否需要发送温度告警
                if (maxTemp >= BusinessConstants.CRITICAL_TEMP_THRESHOLD) {
                    Map<String, Object> alarmData = new HashMap<>();
                    alarmData.put("meter", currentMeter);
                    alarmData.put("temperature", BigDecimal.valueOf(maxTemp).setScale(1, RoundingMode.HALF_UP));
                    alarmMeters.add(alarmData);

                    log.warn("检测到超温米标 - 设备: {}, 通道: {}, 米标: {}, 温度: {:.1f}°C",
                            deviceNo, channelNo, currentMeter, maxTemp);
                }

            } else {
                // 非高温米标的随机异常（概率很低）
                if (random.nextDouble() < 0.0001) {
                    double randomAbnormalTemp = maxTemp + 30.0 + random.nextDouble() * 5.0;
                    maxTemp = randomAbnormalTemp;

                    // 检查随机异常温度是否达到告警阈值
                    if (maxTemp >= BusinessConstants.CRITICAL_TEMP_THRESHOLD) {
                        Map<String, Object> alarmData = new HashMap<>();
                        alarmData.put("meter", currentMeter);
                        alarmData.put("temperature", BigDecimal.valueOf(maxTemp).setScale(1, RoundingMode.HALF_UP));
                        alarmMeters.add(alarmData);

                        log.warn("检测到随机超温米标 - 设备: {}, 通道: {}, 米标: {}, 温度: {:.1f}°C",
                                deviceNo, channelNo, currentMeter, maxTemp);
                    }
                }
            }

            minTemp = Math.max(minTemp, 15.0);
            maxTemperatures.add(BigDecimal.valueOf(maxTemp).setScale(1, RoundingMode.HALF_UP));
            minTemperatures.add(BigDecimal.valueOf(minTemp).setScale(1, RoundingMode.HALF_UP));
        }

        // 发送温度告警数据（如果有）
        if (!alarmMeters.isEmpty() && mqttService != null) {
            sendTemperatureAlarms(deviceNo, channelNo, alarmMeters);
        }

        // 如果所有米标都回到正常状态，重置升温序列
        if (deviceState.allMetersNormal()) {
            deviceState.resetWarmUpSequence();
            log.debug("设备 {} 所有米标回到正常状态，重置升温序列", deviceKey);
        }

        TemperatureMqttDto mqttData = new TemperatureMqttDto();
        mqttData.setDeviceNo(deviceNo);
        mqttData.setChannelNo(channelNo);
        mqttData.setMaxTemperatures(maxTemperatures);
        mqttData.setMinTemperatures(minTemperatures);
        mqttData.setCreateTime(new Date());

        return mqttData;
    }

    /**
     * 发送温度告警数据
     */
    private void sendTemperatureAlarms(String deviceNo, int channelNo, List<Map<String, Object>> alarmMeters) {
        try {
            for (Map<String, Object> alarmMeter : alarmMeters) {
                int meterMark = (int) alarmMeter.get("meter");
                BigDecimal temperature = (BigDecimal) alarmMeter.get("temperature");

                // 构建告警数据
                Map<String, Object> alarmData = new HashMap<>();
                alarmData.put("deviceNo", deviceNo);
                alarmData.put("chanel", channelNo);
                alarmData.put("alarmType", 3); // 温度告警
                alarmData.put("meterMark", meterMark);
                alarmData.put("meterAlarmTemperature", temperature);
                alarmData.put("meterAlarmStatus", 1); // 告警状态：1-告警
                alarmData.put("timestamp", System.currentTimeMillis());
                alarmData.put("sData", String.format("{\"type\":\"temperature\",\"meter_mark\":%d,\"temperature\":%.1f,\"device\":\"%s\",\"channel\":%d}",
                        meterMark, temperature, deviceNo, channelNo));

                // 通过MQTT发送告警
                boolean success = mqttService.publishAlarmData(alarmData);

                if (success) {
                    log.info("温度告警发送成功 - 设备: {}, 通道: {}, 米标: {}, 温度: {}°C",
                            deviceNo, channelNo, meterMark, temperature);
                } else {
                    log.error("温度告警发送失败 - 设备: {}, 通道: {}, 米标: {}, 温度: {}°C",
                            deviceNo, channelNo, meterMark, temperature);
                }
            }

            log.info("批量发送温度告警完成 - 设备: {}, 通道: {}, 告警米标数: {}",
                    deviceNo, channelNo, alarmMeters.size());

        } catch (Exception e) {
            log.error("发送温度告警异常 - 设备: {}, 通道: {}", deviceNo, channelNo, e);
        }
    }

    /**
     * 改进版温度数据生成 - 支持时间维度和升温过程
     */
    public void generateTemperatureDataAdv(String configs) {
        try {
            log.info("开始执行改进版温度数据模拟任务 - {}", LocalDateTime.now());

            if (StringUtils.isEmpty(configs)) {
                log.warn("温度数据模拟任务参数为空，使用默认配置");
                return;
            }

            String[] configArray = configs.split(",");
            int totalRecords = 0;

            for (String config : configArray) {
                String trimmedConfig = config.trim();
                if (StringUtils.isEmpty(trimmedConfig)) {
                    continue;
                }

                String[] parts = trimmedConfig.split("-");
                if (parts.length != 4) {
                    log.error("配置格式错误，跳过: {}", trimmedConfig);
                    continue;
                }

                try {
                    String deviceNo = parts[0].trim();
                    int channelNo = Integer.parseInt(parts[1].trim());
                    int startMeter = Integer.parseInt(parts[2].trim());
                    int endMeter = Integer.parseInt(parts[3].trim());

                    if (startMeter < 1 || endMeter < startMeter) {
                        log.error("米标范围无效，跳过: {} ({} - {})", trimmedConfig, startMeter, endMeter);
                        continue;
                    }

                    // 获取或生成高温米标（保持一致性）
                    List<Integer> highTempMeters = getOrGenerateHighTempMeters(deviceNo, channelNo, startMeter, endMeter);

                    // 更新设备状态并生成温度数据
                    TemperatureData data = generateTemperatureDataWithTimeDimension(
                            deviceNo, channelNo, startMeter, endMeter, highTempMeters);

                    insertTemperatureData(data);
                    totalRecords++;

                    if (totalRecords % 12 == 0) { // 每分钟记录一次日志，避免日志过多
                        log.info("持续生成温度数据 - 设备: {}, 通道: {}, 米标范围: {}-{}, 高温米标数: {}",
                                deviceNo, channelNo, startMeter, endMeter, highTempMeters.size());
                    }

                } catch (NumberFormatException e) {
                    log.error("配置参数格式错误，跳过: {}", trimmedConfig, e);
                }
            }

            log.debug("改进版温度数据模拟任务执行完成 - 生成了 {} 条记录 - {}", totalRecords, LocalDateTime.now());

        } catch (Exception e) {
            log.error("改进版温度数据模拟任务执行失败", e);
        }
    }

    /**
     * 获取或生成高温米标（保持一致性）
     */
    private List<Integer> getOrGenerateHighTempMeters(String deviceNo, int channelNo, int startMeter, int endMeter) {
        String deviceKey = deviceNo + "-" + channelNo;

        return deviceHighTempMeters.computeIfAbsent(deviceKey, k -> {
            List<Integer> highTempMeters = generateShuffledHighTempMeters(deviceNo, channelNo, startMeter, endMeter);
            log.info("为新设备生成高温米标 - 设备: {}, 通道: {}, 高温米标: {}", deviceNo, channelNo, highTempMeters);
            return highTempMeters;
        });
    }

    /**
     * 生成顺序打乱的高温米标
     */
    private List<Integer> generateShuffledHighTempMeters(String deviceNo, int channelNo, int startMeter, int endMeter) {
        List<Integer> highTempMeters = new ArrayList<>();
        int totalMeters = endMeter - startMeter + 1;
        int highTempCount = Math.min(HIGH_TEMP_METER_COUNT, totalMeters);

        if (totalMeters <= highTempCount) {
            for (int i = startMeter; i <= endMeter; i++) {
                highTempMeters.add(i);
            }
            return highTempMeters;
        }

        // 生成候选米标列表
        List<Integer> candidateMeters = new ArrayList<>();
        for (int i = startMeter; i <= endMeter; i++) {
            candidateMeters.add(i);
        }

        // 随机打乱顺序并选择前highTempCount个
        Collections.shuffle(candidateMeters);
        for (int i = 0; i < highTempCount; i++) {
            highTempMeters.add(candidateMeters.get(i));
        }

        // 按米标位置排序（便于显示）
        Collections.sort(highTempMeters);

        log.debug("生成打乱顺序的高温米标 - 设备: {}, 通道: {}, 高温米标: {}",
                deviceNo, channelNo, highTempMeters);

        return highTempMeters;
    }

    /**
     * 生成带时间维度的温度数据
     */
    private TemperatureData generateTemperatureDataWithTimeDimension(String deviceNo, int channelNo,
                                                                     int startMeter, int endMeter,
                                                                     List<Integer> highTempMeters) {
        String deviceKey = deviceNo + "-" + channelNo;
        DeviceTemperatureState deviceState = deviceStates.computeIfAbsent(deviceKey,
                k -> new DeviceTemperatureState());

        int markerCount = endMeter - startMeter + 1;
        List<BigDecimal> maxTemperatures = new ArrayList<>(markerCount);
        List<BigDecimal> minTemperatures = new ArrayList<>(markerCount);

        // 基础温度
        double baseTemp = BASE_TEMP_MIN + random.nextDouble() * (BASE_TEMP_MAX - BASE_TEMP_MIN);

        for (int i = 0; i < markerCount; i++) {
            int currentMeter = startMeter + i;
            double maxTemp = baseTemp + random.nextDouble() * 3.0;
            double minTemp = baseTemp - random.nextDouble() * 2.0;

            // 检查是否是高温米标并处理温度状态
            if (highTempMeters.contains(currentMeter)) {
                MeterTemperatureState meterState = deviceState.meterStates.computeIfAbsent(
                        currentMeter, k -> createNewMeterState(currentMeter, baseTemp, deviceState));

                // 更新米标温度状态
                updateMeterTemperatureState(meterState, deviceState);

                // 使用当前计算出的温度
                maxTemp = meterState.currentTemperature;

                // 记录异常温度
                if (meterState.phase != TemperaturePhase.NORMAL && meterState.phase != TemperaturePhase.WAITING_WARM_UP) {
                    BigDecimal abnormalHighTemp = BigDecimal.valueOf(maxTemp).setScale(1, RoundingMode.HALF_UP);
                    BigDecimal abnormalLowTemp = BigDecimal.valueOf(minTemp).setScale(1, RoundingMode.HALF_UP);
                    insertAbnormalTemperatureData(deviceNo, channelNo, currentMeter, abnormalHighTemp, abnormalLowTemp);
                }

                // 记录温度变化信息（调试用）
                if (meterState.phase == TemperaturePhase.WARMING_UP || meterState.phase == TemperaturePhase.COOLING_DOWN) {
                    double changePer5s = meterState.getTemperatureChangePer5Seconds();
                    log.debug("米标 {} {}中 - 每5秒变化: {:.2f}°C, 当前温度: {:.1f}°C",
                            currentMeter,
                            meterState.phase == TemperaturePhase.WARMING_UP ? "升温" : "降温",
                            changePer5s, maxTemp);
                }
            } else {
                // 非高温米标的随机异常（概率很低）
                if (random.nextDouble() < 0.0001) {
                    double randomAbnormalTemp = maxTemp + 30.0 + random.nextDouble() * 5.0;
                    maxTemp = randomAbnormalTemp;

                    BigDecimal abnormalHighTemp = BigDecimal.valueOf(randomAbnormalTemp).setScale(1, RoundingMode.HALF_UP);
                    BigDecimal abnormalLowTemp = BigDecimal.valueOf(minTemp).setScale(1, RoundingMode.HALF_UP);
                    insertAbnormalTemperatureData(deviceNo, channelNo, currentMeter, abnormalHighTemp, abnormalLowTemp);
                }
            }

            minTemp = Math.max(minTemp, 15.0);
            maxTemperatures.add(BigDecimal.valueOf(maxTemp).setScale(1, RoundingMode.HALF_UP));
            minTemperatures.add(BigDecimal.valueOf(minTemp).setScale(1, RoundingMode.HALF_UP));
        }

        // 如果所有米标都回到正常状态，重置升温序列
        if (deviceState.allMetersNormal()) {
            deviceState.resetWarmUpSequence();
            log.debug("设备 {} 所有米标回到正常状态，重置升温序列", deviceKey);
        }

        TemperatureData data = new TemperatureData();
        data.setDeviceNo(deviceNo);
        data.setChannelNo(channelNo);
        data.setMaxTemperatures(JSON.toJSONString(maxTemperatures));
        data.setMinTemperatures(JSON.toJSONString(minTemperatures));
        data.setCreateTime(LocalDateTime.now());
        data.setStartMeter(startMeter);
        data.setEndMeter(endMeter);

        return data;
    }

    /**
     * 创建新的米标温度状态
     */
    private MeterTemperatureState createNewMeterState(int meter, double baseTemp, DeviceTemperatureState deviceState) {
        MeterTemperatureState state = new MeterTemperatureState();
        state.meter = meter;
        state.phase = TemperaturePhase.WAITING_WARM_UP;
        state.scheduledWarmUpTime = deviceState.getNextWarmUpStartTime();
        state.phaseStartTime = LocalDateTime.now();
        state.startTemperature = baseTemp;
        state.targetTemperature = baseTemp;
        state.currentTemperature = baseTemp;

        log.debug("创建新的米标状态 - 米标: {}, 计划升温时间: {}", meter, state.scheduledWarmUpTime);
        return state;
    }

    /**
     * 更新米标温度状态
     */
    private void updateMeterTemperatureState(MeterTemperatureState meterState, DeviceTemperatureState deviceState) {
        LocalDateTime now = LocalDateTime.now();

        // 如果设备在冷却期，保持正常温度
        if (deviceState.isInCoolDownPeriod() &&
                (meterState.phase == TemperaturePhase.NORMAL || meterState.phase == TemperaturePhase.WAITING_WARM_UP)) {
            meterState.phase = TemperaturePhase.NORMAL;
            meterState.scheduledWarmUpTime = null;
            return;
        }

        // 处理等待升温状态
        if (meterState.phase == TemperaturePhase.WAITING_WARM_UP) {
            if (meterState.isWarmUpTimeReached()) {
                // 到达计划升温时间，开始升温
                meterState.phase = TemperaturePhase.WARMING_UP;
                meterState.phaseStartTime = now;
                meterState.startTemperature = meterState.currentTemperature;
                meterState.targetTemperature = BASE_TEMP_MAX + ABNORMAL_TEMP_BASE + random.nextDouble() * ABNORMAL_TEMP_RANGE;

                // 修正日志格式 - 使用正确的占位符
                log.info("开始升温 - 米标: {}, 起始温度: {:.1f}, 目标温度: {:.1f}, 升温时间: {}秒",
                        meterState.meter,
                        meterState.startTemperature,
                        meterState.targetTemperature,
                        WARM_UP_DURATION_SECONDS);  // 使用常量而不是计算值
            } else {
                // 还未到升温时间，保持当前温度
                meterState.currentTemperature = meterState.startTemperature;
                return;
            }
        }

        // 更新当前温度
        meterState.updateCurrentTemperature();

        // 检查阶段是否完成并转换到下一阶段
        if (meterState.isPhaseCompleted()) {
            switch (meterState.phase) {
                case WARMING_UP:
                    // 进入高温持续阶段
                    meterState.phase = TemperaturePhase.HIGH_TEMP;
                    meterState.phaseStartTime = now;
                    meterState.startTemperature = meterState.currentTemperature;
                    meterState.baseHighTemperature = meterState.currentTemperature; // 设置高温基础温度
                    meterState.targetTemperature = meterState.currentTemperature;
                    log.info("进入高温持续 - 米标: {}, 基础温度: {:.1f}, 持续时间: {}秒",
                            meterState.meter, meterState.baseHighTemperature, HIGH_TEMP_DURATION_SECONDS);
                    break;

                case HIGH_TEMP:
                    // 开始降温
                    meterState.phase = TemperaturePhase.COOLING_DOWN;
                    meterState.phaseStartTime = now;
                    meterState.startTemperature = meterState.currentTemperature;
                    meterState.targetTemperature = BASE_TEMP_MIN + random.nextDouble() * (BASE_TEMP_MAX - BASE_TEMP_MIN);
                    log.info("开始降温 - 米标: {}, 起始温度: {:.1f}, 目标温度: {:.1f}, 降温时间: {}秒",
                            meterState.meter, meterState.startTemperature, meterState.targetTemperature, COOL_DOWN_DURATION_SECONDS);
                    break;

                case COOLING_DOWN:
                    // 降温完成，回到等待状态
                    meterState.phase = TemperaturePhase.WAITING_WARM_UP;
                    meterState.phaseStartTime = now;
                    meterState.startTemperature = meterState.currentTemperature;
                    meterState.targetTemperature = meterState.currentTemperature;
                    meterState.scheduledWarmUpTime = deviceState.getNextWarmUpStartTime();
                    deviceState.lastCoolDownTime = now; // 记录冷却完成时间
                    log.info("降温完成 - 米标: {}, 当前温度: {:.1f}, 下次升温时间: {}",
                            meterState.meter, meterState.currentTemperature, meterState.scheduledWarmUpTime);
                    break;
            }
        }
    }

    // 以下方法保持不变...
    /**
     * 插入异常温度数据到异常表
     */
    private void insertAbnormalTemperatureData(String deviceNo, int channelNo, int meter,
                                               BigDecimal maxTemperature, BigDecimal minTemperature) {
        String sql = "INSERT INTO pj_realtime_temperature_data_issue " +
                "(device_no, channel_no, meter, max_temperatures, min_temperatures, create_time) " +
                "VALUES (?, ?, ?, ?, ?, ?)";

        try {
            int result = jdbcTemplate.update(sql,
                    deviceNo,
                    channelNo,
                    meter,
                    maxTemperature,
                    minTemperature,
                    LocalDateTime.now());

            if (result > 0) {
                log.debug("成功插入异常温度数据 - 设备: {}, 通道: {}, 米标: {}, 温度: {}",
                        deviceNo, channelNo, meter, maxTemperature);
            }

        } catch (Exception e) {
            log.error("插入异常温度数据失败 - 设备: {}, 通道: {}, 米标: {}",
                    deviceNo, channelNo, meter, e);
        }
    }

    /**
     * 插入温度数据到数据库
     */
    private void insertTemperatureData(TemperatureData data) {
        String sql = "INSERT INTO pj_realtime_temperature_data " +
                "(device_no, channel_no, max_temperatures, min_temperatures, create_time, start_meter, end_meter) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?)";

        try {
            int result = jdbcTemplate.update(sql,
                    data.getDeviceNo(),
                    data.getChannelNo(),
                    data.getMaxTemperatures(),
                    data.getMinTemperatures(),
                    data.getCreateTime(),
                    data.getStartMeter(),
                    data.getEndMeter());

            if (result > 0) {
                int arrayLength = data.getEndMeter() - data.getStartMeter() + 1;
                log.debug("成功插入温度数据 - 设备: {}, 通道: {}, 米标范围: {}-{}, 数组长度: {}",
                        data.getDeviceNo(), data.getChannelNo(),
                        data.getStartMeter(), data.getEndMeter(), arrayLength);
            }

        } catch (Exception e) {
            log.error("插入温度数据失败 - 设备: {}, 通道: {}", data.getDeviceNo(), data.getChannelNo(), e);
            throw e;
        }
    }

    /**
     * 温度数据实体类
     */
    public static class TemperatureData {
        private String deviceNo;
        private Integer channelNo;
        private String maxTemperatures;
        private String minTemperatures;
        private LocalDateTime createTime;
        private Integer startMeter;
        private Integer endMeter;

        // getter and setter methods
        public String getDeviceNo() { return deviceNo; }
        public void setDeviceNo(String deviceNo) { this.deviceNo = deviceNo; }

        public Integer getChannelNo() { return channelNo; }
        public void setChannelNo(Integer channelNo) { this.channelNo = channelNo; }

        public String getMaxTemperatures() { return maxTemperatures; }
        public void setMaxTemperatures(String maxTemperatures) { this.maxTemperatures = maxTemperatures; }

        public String getMinTemperatures() { return minTemperatures; }
        public void setMinTemperatures(String minTemperatures) { this.minTemperatures = minTemperatures; }

        public LocalDateTime getCreateTime() { return createTime; }
        public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; }

        public Integer getStartMeter() { return startMeter; }
        public void setStartMeter(Integer startMeter) { this.startMeter = startMeter; }

        public Integer getEndMeter() { return endMeter; }
        public void setEndMeter(Integer endMeter) { this.endMeter = endMeter; }
    }
}